
#ifndef ENGINE_HOOK_H
#define ENGINE_HOOK_H
#include "Base.h"
#include "class.h"
#include "struct.h"
#include "Dobby/dobby.h"
#include "ByNameModding/Tools.h"
#include "ByNameModding/fake_dlfcn.h"
#include "ByNameModding/Il2Cpp.h"
#include "xdl/include/xdl.h"  // 添加 xdl 头文件

extern MonoArray<void**>* (*Object_FindObjectsOfType)(void*);
extern bool* ( *Object_IsNativeObjectAlive)(void *object);
extern MonoString* (*Object_get_name)(void*);
extern void* (*Type_GetTypeName)(MonoString*);
extern void* (*il2cpp_thread_attach)(void* domain);
extern void* (*il2cpp_domain_get)();
extern bool m_CachedPtr(void* unity_obj);
extern Transform* (*Component_get_transform)(void* instance);
extern Vector3(* Transform_get_position)(void* instance);
extern Transform* (* GameObject_get_transform)(void* instance);
extern Camera* (*Camera_get_main)();
extern Vector3(*Camera_WorldToScreen)(Camera* camera, Vector3 position);
extern bool* (*get_isTrigger)(void* instance);
extern void(*set_localScale)(Transform* instance,Vector3);

// Add the missing extern declarations:
extern Transform* (*GetBoneTransform)(Animator*,int);
extern bool* (*get_isHuman)(Animator*);
extern Vector3 (*get_forward)(void *instance);

#if defined(__aarch64__)
#define GET_METHOD(assembly, namespace, klass, method, paramCount) \
        (void*)(uintptr_t)Il2CppGetMethodOffset(assembly, namespace, klass, method, paramCount)
#else
#define GET_METHOD(assembly, namespace, klass, method, paramCount) \
        (void*)(uintptr_t)Il2CppGetMethodOffset(assembly, namespace, klass, method, paramCount)
#endif

void initializeFunctionPointers();

#endif

#include "hook.h"

bool m_CachedPtr(void* unity_obj) {
    if (!unity_obj) return false;
#if defined(__aarch64__)
    return (*(uintptr_t*)((uintptr_t)unity_obj + 0x10) != 0);
#else
    return (*(uintptr_t*)((uintptr_t)unity_obj + 0x8) != 0);
#endif
}
bool* (*Object_IsNativeObjectAlive)(void *object);
Transform* (*GetBoneTransform)(Animator*,int);
bool* (*get_isHuman)(Animator*);
Transform* (* GameObject_get_transform)(void* instance);
Transform* (* Component_get_transform)(void* instance);
MonoArray<void**>* (*Object_FindObjectsOfType)(void*);
MonoString* (*Object_get_name)(void*);
void* (*Type_GetTypeName)(MonoString*);
void* (*il2cpp_thread_attach)(void*);
void* (*il2cpp_domain_get)();
Vector3(*Transform_get_position)(void* instance);
Vector3(*Camera_WorldToScreen)(Camera* camera, Vector3 position);
Camera* (*Camera_get_main)();
Vector3 (*get_forward)(void *instance);
void (*set_localScale)(Transform* instance, Vector3 Scale);
bool* (*get_isTrigger)(void* instance);
void initializeFunctionPointers()
{
    void* handle = xdl_open("libil2cpp.so", XDL_DEFAULT);
    while (!handle) {
        handle = xdl_open("libil2cpp.so", XDL_DEFAULT);
        sleep(1);
    }

    get_isTrigger = (bool* (*)(void* instance))GET_METHOD("UnityEngine.PhysicsModule.dll", "UnityEngine", "Collider", "get_isTrigger", 0);
    get_forward = (Vector3 (*)(void*))GET_METHOD("UnityEngine.dll", "UnityEngine", "Transform", "get_forward", 0);
    set_localScale = (void(*)(Transform*,Vector3))GET_METHOD("UnityEngine.dll", "UnityEngine", "Transform", "set_localScale", 1);
    Object_IsNativeObjectAlive = (bool* (*)(void*))GET_METHOD("UnityEngine.dll", "UnityEngine", "Object", "IsNativeObjectAlive", 1);
    GetBoneTransform = (Transform* (*) (Animator*,int))GET_METHOD("UnityEngine.AnimationModule.dll", "UnityEngine", "Animator", "GetBoneTransform", 1);
    get_isHuman = (bool* (*) (Animator*))GET_METHOD("UnityEngine.AnimationModule.dll", "UnityEngine", "Animator", "get_isHuman", 0);
    Camera_WorldToScreen = (Vector3 (*) (Camera* camera,Vector3 Pos))GET_METHOD("UnityEngine.dll", "UnityEngine", "Camera", "WorldToScreenPoint", 1);
    Camera_get_main = (Camera * (*)())GET_METHOD("UnityEngine.dll", "UnityEngine", "Camera", "get_main", 0);
    GameObject_get_transform = (Transform * (*)(void*))GET_METHOD("UnityEngine.dll", "UnityEngine", "GameObject", "get_transform", 0);
    Transform_get_position = (Vector3(*)(void*))GET_METHOD("UnityEngine.dll", "UnityEngine", "Transform", "get_position", 0);
    Component_get_transform = (Transform* (*)(void*))GET_METHOD("UnityEngine.dll", "UnityEngine", "Component", "get_transform", 0);
	Object_FindObjectsOfType = (MonoArray<void**>* (*) (void* Type))GET_METHOD("UnityEngine.dll", "UnityEngine", "Object", "FindObjectsOfType", 1);
	Type_GetTypeName = (void* (*) (MonoString * Name))GET_METHOD("mscorlib.dll", "System", "Type", "GetType", 1);
	Object_get_name = (MonoString* (*) (void* obj))GET_METHOD("UnityEngine.CoreModule.dll", "UnityEngine", "Object", "ToString", 0);
    il2cpp_thread_attach = (void* (*) (void*domain))xdl_sym(handle, "il2cpp_thread_attach", nullptr);
    il2cpp_domain_get = (void* (*)())xdl_sym(handle, "il2cpp_domain_get", nullptr);
}
#include "HookEgl.h"
#include <stdio.h>
#include <android/native_window_jni.h>
#include <android/log.h>
#include <string>
#include <vector>
#include <map>
#include <algorithm>
#include <pthread.h>
#include <dlfcn.h>

std::atomic<bool> g_RestartDrawing(false); 
bool g_Initialized = false;
bool initImGui = false;

void* Type;
ANativeWindow *ANativeWindow_p;

static std::vector<ItemInfo> items;

// 新增：对象名称统计结构
struct ObjectTypeInfo {
    std::string name;
    int count;
    bool selected;
    
    ObjectTypeInfo(const std::string& n, int c) : name(n), count(c), selected(false) {}
};

// 新增：存储对象类型信息的容器
static std::vector<ObjectTypeInfo> objectTypes;
static std::map<std::string, std::vector<ItemInfo>> groupedItems;

struct Game_Screen {
	static int Width;
	static int Height;
	static int ScreenWidth;
	static int ScreenHeight;
	static bool setup;
};

int Game_Screen::Width = 0;
int Game_Screen::Height = 0;
int Game_Screen::ScreenWidth = 0;
int Game_Screen::ScreenHeight = 0;
bool Game_Screen::setup = false;
bool OpenEsp = false;
Camera* Main_Camera;
Animator* animator;

#define LOG_TAG  "连接输出"
#define ALOGD(...)  logMessage(__VA_ARGS__)

// 自定义日志缓冲区
std::vector<std::string> logMessages;

// 触摸坐标
float touchX = 0.0f, touchY = 0.0f;
bool touchActive = false;

// 互斥锁，用于保护共享资源
pthread_mutex_t logMutex = PTHREAD_MUTEX_INITIALIZER;

// 自定义日志输出函数
void logMessage(const char* format, ...) {
    va_list args;
    va_start(args, format);

    char buffer[1024];
    vsnprintf(buffer, sizeof(buffer), format, args);
    va_end(args);

    // 使用互斥锁保护日志缓冲区
    pthread_mutex_lock(&logMutex);
    // 将日志信息添加到缓冲区
    logMessages.push_back(buffer);
    if (logMessages.size() > 100) {
        logMessages.erase(logMessages.begin());  // 保持缓冲区最多 100 条日志
    }
    pthread_mutex_unlock(&logMutex);

    // 输出到 Android Logcat
    __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, "%s", buffer);
}

// 原始函数指针
EGLBoolean(*old_eglSwapBuffers)(EGLDisplay dpy, EGLSurface surface);
ANativeWindow* (*old_ANativeWindow_fromSurface)(JNIEnv* env, jobject surface);
void (*old_input)(void *thiz, void *ex_ab, void *ex_ac);

// Hook函数实现
void hook_input(void *thiz, void *ex_ab, void *ex_ac) {
    try {
        old_input(thiz, ex_ab, ex_ac);
        if (g_Initialized) {
            ImGui_ImplAndroid_HandleInputEvent((AInputEvent *)thiz); 
        }
    } catch (const std::exception &e) {
        return;
    }
}

ANativeWindow* hook_ANativeWindow_fromSurface(JNIEnv* env, jobject surface) {
    ANativeWindow_p = old_ANativeWindow_fromSurface(env, surface); // 调用原始函数
    Game_Screen::ScreenWidth = ANativeWindow_getWidth(ANativeWindow_p);  // 获取屏幕宽度
    Game_Screen::ScreenHeight = ANativeWindow_getHeight(ANativeWindow_p); // 获取屏幕高度
    ALOGD("自动获取的屏幕尺寸：宽=%d，高=%d", Game_Screen::ScreenWidth, Game_Screen::ScreenHeight);
    return ANativeWindow_p;
}

// 在全局变量部分添加以下内容
bool autoRefresh = false;
float refreshInterval = 0.1f; // 默认0.1秒刷新一次
std::chrono::steady_clock::time_point lastRefreshTime;

// 修改的RefreshItems函数
void RefreshItems()
{
    items.clear();
    groupedItems.clear();
    objectTypes.clear();
    
    void* itemType = Type_GetTypeName(Il2CppString::CreateMonoString("UnityEngine.Transform,UnityEngine.CoreModule.dll"));
    if (itemType)
    {
        MonoArray<void**>* Objects = Object_FindObjectsOfType(itemType);
        std::map<std::string, int> nameCount;
        
        for (int i = 0; i < Objects->getLength(); i++)
        {
            auto obj = Objects->getPointer()[i];
            if (obj && m_CachedPtr(obj) && Object_IsNativeObjectAlive(obj))
            {
                ItemInfo item;
                item.Ptr = obj;
                
                MonoString* nameStr = Object_get_name(obj);
                std::string name = nameStr ? nameStr->ToString() : "Unknown";
                
                items.push_back(item);
                groupedItems[name].push_back(item);
                nameCount[name]++;
            }
        }
        
        // 创建对象类型信息并按数量排序
        for (const auto& pair : nameCount) {
            objectTypes.emplace_back(pair.first, pair.second);
        }
        
        // 按数量从多到少排序
        std::sort(objectTypes.begin(), objectTypes.end(), 
                  [](const ObjectTypeInfo& a, const ObjectTypeInfo& b) {
                      return a.count > b.count;
                  });
    }
    ALOGD("已刷新对象列表，共 %d 个对象，%d 种类型", items.size(), objectTypes.size());
}

// 修改Showmenu函数
void Showmenu()
{
    ImGuiIO& io = ImGui::GetIO();
    static float f = 0.0f;
    static int counter = 0;

    ImGui::Begin("Hello, world!", nullptr, ImGuiWindowFlags_HorizontalScrollbar);

    if (Camera_get_main) {
        Main_Camera = Camera_get_main();
    }

    // 手动刷新按钮
    if (ImGui::Button("刷新对象"))
    {
        RefreshItems();
    }

    ImGui::SameLine();

    // 自动刷新开关
    ImGui::Checkbox("自动刷新", &autoRefresh);
    
    // 刷新频率滑块
    if (autoRefresh) {
        ImGui::SliderFloat("刷新频率(秒)", &refreshInterval, 0.001f, 0.1f);
        
        // 检查是否需要自动刷新
        auto now = std::chrono::steady_clock::now();
        auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(now - lastRefreshTime).count() / 1000.0f;
        
        if (elapsed >= refreshInterval) {
            RefreshItems();
            lastRefreshTime = now;
        }
    }

    if (ImGui::Button(OpenEsp ? "ESP开启" : "ESP关闭"))
    {
        OpenEsp = !OpenEsp;
    }

    ImGui::Text("Main_Camera的地址 = %p", Main_Camera);
    ImGui::Text("对象数量 = %d", items.size());
    ImGui::Text("对象类型 = %d", objectTypes.size());

    ImGui::Separator();
    
    // 新增：对象类型选择列表
    ImGui::Text("对象类型选择 (按数量排序):");
    
    // 添加全选/全不选按钮
    if (ImGui::Button("全选")) {
        for (auto& objType : objectTypes) {
            objType.selected = true;
        }
    }
    ImGui::SameLine();
    if (ImGui::Button("全不选")) {
        for (auto& objType : objectTypes) {
            objType.selected = false;
        }
    }
    ImGui::SameLine();
    if (ImGui::Button("反选")) {
        for (auto& objType : objectTypes) {
            objType.selected = !objType.selected;
        }
    }

    // 滚动区域显示对象类型列表
    ImGui::BeginChild("ObjectTypeList", ImVec2(0, 300), true);
    
    for (int i = 0; i < objectTypes.size(); i++) {
        auto& objType = objectTypes[i];
        
        // 格式化显示：名称 (数量)
        std::string displayName = objType.name + " (" + std::to_string(objType.count) + ")";
        
        if (ImGui::Checkbox(displayName.c_str(), &objType.selected)) {
            ALOGD("选择状态改变: %s = %s", objType.name.c_str(), objType.selected ? "true" : "false");
        }
    }
    
    ImGui::EndChild();

    ImGui::Separator();

    // 统计选中的对象数量
    int selectedCount = 0;
    for (const auto& objType : objectTypes) {
        if (objType.selected) {
            selectedCount += objType.count;
        }
    }
    
    ImGui::Text("已选择绘制对象数量: %d", selectedCount);

    // 绘制选中的对象
    if (OpenEsp && Main_Camera) {
        for (const auto& objType : objectTypes) {
            if (objType.selected) {
                auto it = groupedItems.find(objType.name);
                if (it != groupedItems.end()) {
                    for (const auto& item : it->second) {
                        if (item.Ptr && m_CachedPtr(item.Ptr) && Object_IsNativeObjectAlive(item.Ptr)) {
                            auto itemobj = (GameObject*)item.Ptr;
                            auto Point = Main_Camera->WoldToScreen(itemobj->GetObjectTrans()->GetPosition());

                            if (Point.Z > 0) {
                                ImGui::GetForegroundDrawList()->AddText(
                                    { Point.X, glHeight - Point.Y },
                                    ImColor(255, 0, 0, 255),
                                    objType.name.c_str()
                                );
                            }
                        }
                    }
                }
            }
        }
    }
    
    ImGui::End();
}

EGLBoolean hook_eglSwapBuffers(EGLDisplay dpy, EGLSurface surface) {
	eglQuerySurface(dpy, surface, EGL_WIDTH, &Game_Screen::Width);
	eglQuerySurface(dpy, surface, EGL_HEIGHT, &Game_Screen::Height);
	glWidth = Game_Screen::Width;
	glHeight = Game_Screen::Height;

    if (Game_Screen::Width <= 0 || Game_Screen::Height <= 0) {
        return old_eglSwapBuffers(dpy, surface);
    }

	try {
		if (!initImGui) {
			IMGUI_CHECKVERSION();
			ImGui::CreateContext();
			ImGuiIO& io = ImGui::GetIO();
			
			// 配置ImGui以支持多点触控
			io.ConfigFlags |= ImGuiConfigFlags_IsTouchScreen;
			io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors;

			// 设置显示大小
			io.DisplaySize = ImVec2((float)glWidth, (float)glHeight);
			
			ImGui::StyleColorsLight();

			// 初始化Android平台
			ImGui_ImplAndroid_Init(ANativeWindow_p);
			// 初始化OpenGL ES 3
			ImGui_ImplOpenGL3_Init("#version 300 es");

			// 字体设置
			ImFontConfig font_cfg;
			font_cfg.SizePixels = 22.0f;
			io.Fonts->AddFontFromMemoryTTF((void*)font_v, font_v_size, 28.0f, nullptr, io.Fonts->GetGlyphRangesChineseFull());
			io.Fonts->AddFontDefault(&font_cfg);
			
			// 缩放样式
			ImGui::GetStyle().ScaleAllSizes(6.0f);
			
			g_Initialized = true;      
			initImGui = true;
			
			ALOGD("ImGui初始化完成");
		}

		ImGuiIO& io = ImGui::GetIO();
		io.DisplaySize = ImVec2((float)glWidth, (float)glHeight);

		// 开始新帧
		ImGui_ImplOpenGL3_NewFrame();
		ImGui_ImplAndroid_NewFrame(glWidth, glHeight);
		ImGui::NewFrame();
		ImGui::GetIO().FontGlobalScale = 1.0f;

		Showmenu();

		ImGui::EndFrame();
		ImGui::Render();
		glViewport(0, 0, glWidth, glHeight);

		ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());

		return old_eglSwapBuffers(dpy, surface);
	}
	catch (...) {
		g_RestartDrawing = true;
		return EGL_FALSE;
	}
}

void Egl_hooks() {
    // 获取并钩取 InputConsumer::initializeMotionEvent
    void *sym_input = DobbySymbolResolver("/system/lib64/libinput.so", 
                                        "_ZN7android13InputConsumer21initializeMotionEventEPNS_11MotionEventEPKNS_12InputMessageE"); 
    if (sym_input) {
        DobbyHook(sym_input, (void *)hook_input, (void **)&old_input);
        ALOGD("InputConsumer::initializeMotionEvent 钩取成功: %p", sym_input);
    }

    // 获取并钩取 eglSwapBuffers（直接通过 libEGL.so 的符号）
    void *eglSwapBuffersAddr = DobbySymbolResolver("/system/lib64/libEGL.so", "eglSwapBuffers");
    if (eglSwapBuffersAddr) {
        DobbyHook(eglSwapBuffersAddr, (void*)hook_eglSwapBuffers, (void**)&old_eglSwapBuffers);
        ALOGD("eglSwapBuffers 钩取成功: %p", eglSwapBuffersAddr);
    }

    // 获取并钩取 ANativeWindow_fromSurface（直接通过 libnativewindow.so 的符号）
    void *ANativeWindow_fromSurfaceAddr = DobbySymbolResolver("/system/lib64/libnativewindow.so", "ANativeWindow_fromSurface");
    if (ANativeWindow_fromSurfaceAddr) {
        DobbyHook(ANativeWindow_fromSurfaceAddr, (void*)hook_ANativeWindow_fromSurface, (void**)&old_ANativeWindow_fromSurface);
        ALOGD("ANativeWindow_fromSurface 钩取成功: %p", ANativeWindow_fromSurfaceAddr);
    }

    ALOGD("所有钩取操作完成");
}

void* main_thread(void *) {
    ALOGD("主线程启动");
    
    Egl_hooks();
    
    Il2CppAttach();
    
    initializeFunctionPointers();
    
    ALOGD("初始化完成");
    return nullptr;
}

void hack_thread() {
    pthread_t thread;
    if (pthread_create(&thread, nullptr, main_thread, nullptr) == 0) {
        ALOGD("主线程创建成功");
        pthread_detach(thread);
    } else {
        ALOGD("主线程创建失败");
    }
}